package io.github.echarts.model.adapter;

import io.github.echarts.model.ChartModel;
import io.github.echarts.model.CategoryManager;
import io.github.echarts.model.context.ConfigurationContext;
import io.github.echarts.model.series.SeriesDataManager;
import io.github.echarts.model.theme.DefaultValueProviderFactory;
import io.github.echarts.model.theme.Theme;
import io.github.echarts.model.theme.ThemeManager;
import io.github.echarts.option.EChartOption;
import io.github.echarts.option.component.Grid;
import io.github.echarts.option.component.Legend;
import io.github.echarts.option.component.Title;
import io.github.echarts.option.component.Axis;
import io.github.echarts.option.series.SeriesOption;

import java.util.List;

/**
 * 配置选项到模型的适配器。
 * 该类负责将外部配置格式转换为内部模型结构，
 * 使模型独立于特定的配置格式。
 */
public class OptionModelAdapter {
    
    // 专门处理系列数据的适配器
    private static final SeriesAdapter seriesAdapter = new SeriesAdapter();
    
    // 专门处理坐标系的适配器
    private static final CoordinateSystemAdapter coordinateSystemAdapter = new CoordinateSystemAdapter();
    
    // 专门处理其他组件的适配器
    private static final ComponentAdapter componentAdapter = new ComponentAdapter();
    
    // 基本属性适配器
    private static final BasicPropertyAdapter basicPropertyAdapter = new BasicPropertyAdapter();
    
    /**
     * 将EChartOption适配为ChartModel。
     * <p>
     * 本方法实现了"一站式"模型构建，执行从配置选项到完整可渲染模型的全部转换过程。
     * 处理流程包括：
     * 1. 创建基础模型
     * 2. 设置基本属性
     * 3. 初始化类别管理器
     * 4. 初始化系列数据管理器
     * 5. 转换系列数据
     * 6. 处理数据和准备配置上下文
     * 7. 应用默认配置和主题
     * 8. 基础布局计算
     * 9. 创建并配置坐标系
     * 10. 转换其他组件
     * 11. 细节布局优化
     * </p>
     *
     * @param option 要适配的EChartOption
     * @param width 图表宽度
     * @param height 图表高度
     * @return 表示配置的ChartModel
     */
    public static ChartModel adaptFromOption(EChartOption option, int width, int height) {
        // 1. 创建基础模型
        ChartModel model = new ChartModel(width, height);
        
        // 创建配置上下文
        ConfigurationContext context = new ConfigurationContext(width, height);
        
        // 2. 设置基本属性和样式
        basicPropertyAdapter.adaptBasicProperties(option, model, context);
        
        // 3. 初始化类别管理器
        CategoryManager categoryManager = new CategoryManager();
        model.setCategoryManager(categoryManager);
        // 从数据源中提取类别数据（后续由SeriesAdapter处理）
        
        // 4. 初始化系列数据管理器
        SeriesDataManager seriesDataManager = new SeriesDataManager();
        model.setSeriesDataManager(seriesDataManager);
        
        // 5. 转换系列数据(创建系列模型)
        seriesAdapter.adaptSeries(option, model, context);
        
        // 6. 处理数据(计算数据范围)和准备配置上下文
        seriesAdapter.processSeriesDataAndCreateContext(model, option, context);
        
        // 7. 应用默认配置和主题
        applyDefaultsAndTheme(option, context);
        
        // 如果在选项中指定了主题，设置到模型中
        if (option.getTheme() != null) {
            model.setThemeByName(option.getTheme());
        }
        
        // 8. 基础布局计算
        calculatePreliminaryLayout(model);
        
        // 9. 根据数据特性和网格区域创建并配置坐标系
        coordinateSystemAdapter.adaptCoordinateSystems(option, model, context);
        
        // 10. 转换其他组件
        componentAdapter.adaptComponents(option, model, context);
        
        // 11. 细节布局优化(暂未实现，后续任务)
        // refineLayout(model);
        
        return model;
    }
    
    /**
     * 执行基础布局计算
     * 
     * @param model 图表模型
     */
    private static void calculatePreliminaryLayout(ChartModel model) {
        // 使用模型的布局管理器进行布局计算
        model.getLayoutManager().calculatePreliminaryLayout(model);
    }
    
    /**
     * 应用默认值和主题到配置
     * 
     * @param option ECharts配置选项
     * @param context 配置上下文
     */
    private static void applyDefaultsAndTheme(EChartOption option, ConfigurationContext context) {
        // 获取默认值提供者工厂
        DefaultValueProviderFactory providerFactory = DefaultValueProviderFactory.getInstance();
        
        // 获取当前主题
        ThemeManager themeManager = ThemeManager.getInstance();
        Theme theme = themeManager.getCurrentTheme();
        
        // 如果配置中指定了主题，则使用指定主题
        if (option.getTheme() != null) {
            Theme specifiedTheme = themeManager.getTheme(option.getTheme());
            if (specifiedTheme != null) {
                theme = specifiedTheme;
            }
        }
        
        // 为标题应用默认值和主题
        applyToTitle(option.getTitle(), context, theme, providerFactory);
        
        // 为图例应用默认值和主题
        applyToLegend(option.getLegend(), context, theme, providerFactory);
        
        // 为X轴应用默认值和主题
        applyToAxis(option.getXAxis(), context, theme, providerFactory);
        
        // 为Y轴应用默认值和主题
        applyToAxis(option.getYAxis(), context, theme, providerFactory);
        
        // 为网格应用默认值和主题
        applyToGrid(option.getGrid(), context, theme, providerFactory);
        
        // 为提示框应用默认值和主题（暂时注释掉，等Tooltip完全实现后再启用）
        // applyToTooltip(option.getTooltip(), context, theme, providerFactory);
        
        // 为系列应用默认值和主题
        applyToSeries(option.getSeries(), context, theme, providerFactory);
    }
    
    /**
     * 为标题应用默认值和主题
     * 
     * @param title 标题配置
     * @param context 配置上下文
     * @param theme 主题
     * @param providerFactory 默认值提供者工厂
     */
    private static void applyToTitle(Title title, ConfigurationContext context, 
                                     Theme theme, DefaultValueProviderFactory providerFactory) {
        if (title != null) {
            providerFactory.applyDefaultsAndTheme(title, context, theme);
        }
    }
    
    /**
     * 为图例应用默认值和主题
     * 
     * @param legend 图例配置
     * @param context 配置上下文
     * @param theme 主题
     * @param providerFactory 默认值提供者工厂
     */
    private static void applyToLegend(Legend legend, ConfigurationContext context, 
                                      Theme theme, DefaultValueProviderFactory providerFactory) {
        if (legend != null) {
            providerFactory.applyDefaultsAndTheme(legend, context, theme);
        }
    }
    
    /**
     * 为坐标轴应用默认值和主题
     * 
     * @param axis 坐标轴配置
     * @param context 配置上下文
     * @param theme 主题
     * @param providerFactory 默认值提供者工厂
     */
    private static void applyToAxis(Axis axis, ConfigurationContext context, 
                                   Theme theme, DefaultValueProviderFactory providerFactory) {
        if (axis != null) {
            providerFactory.applyDefaultsAndTheme(axis, context, theme);
        }
    }
    
    /**
     * 为网格应用默认值和主题
     * 
     * @param grid 网格配置
     * @param context 配置上下文
     * @param theme 主题
     * @param providerFactory 默认值提供者工厂
     */
    private static void applyToGrid(Grid grid, ConfigurationContext context, 
                                   Theme theme, DefaultValueProviderFactory providerFactory) {
        if (grid != null) {
            providerFactory.applyDefaultsAndTheme(grid, context, theme);
        }
    }
    
    /* 暂时注释掉，等Tooltip完全实现后再启用
    **
     * 为提示框应用默认值和主题
     * 
     * @param tooltip 提示框配置
     * @param context 配置上下文
     * @param theme 主题
     * @param providerFactory 默认值提供者工厂
     *
    private static void applyToTooltip(Tooltip tooltip, ConfigurationContext context, 
                                     Theme theme, DefaultValueProviderFactory providerFactory) {
        if (tooltip != null) {
            providerFactory.applyDefaultsAndTheme(tooltip, context, theme);
        }
    }
    */
    
    /**
     * 为系列应用默认值和主题
     * 
     * @param series 系列配置
     * @param context 配置上下文
     * @param theme 主题
     * @param providerFactory 默认值提供者工厂
     */
    @SuppressWarnings("unchecked")
    private static void applyToSeries(Object series, ConfigurationContext context, 
                                     Theme theme, DefaultValueProviderFactory providerFactory) {
        if (series == null) {
            return;
        }
        
        // 处理系列列表
        if (series instanceof List) {
            List<SeriesOption> seriesList = (List<SeriesOption>) series;
            for (SeriesOption seriesOption : seriesList) {
                providerFactory.applyDefaultsAndTheme(seriesOption, context, theme);
            }
        } 
        // 处理系列数组
        else if (series instanceof SeriesOption[]) {
            SeriesOption[] seriesArray = (SeriesOption[]) series;
            for (SeriesOption seriesOption : seriesArray) {
                providerFactory.applyDefaultsAndTheme(seriesOption, context, theme);
            }
        }
        // 处理单个系列
        else if (series instanceof SeriesOption) {
            providerFactory.applyDefaultsAndTheme((SeriesOption)series, context, theme);
        }
    }
} 